package Structures;

import java.util.NoSuchElementException;

/**
 * Instancia colas de prioridad usadas para el algoritmo de dijkstra.
 * @author Jeremy
 * @author Rodrigo
 * @author Gabriel
 * @author Alexandre
 */
public class PriorityQueue {

    private SLLNode _first; //Primer elemento de la cola.
    private int _length; //Tamaño de la cola.
    
    /**
     * Construye una nueva cola de prioridad con su primer elemento referenciado
     * a nulo y su tamaño en 0.
     */
    public PriorityQueue () {
        _first = null;
        _length = 0;
    }
    
    //////////////////////////////Getters y setters/////////////////////////////
    /**
     * Obtiene el tamaño de la cola.
     * @return Tamaño de la cola
     */
    public int getSize () {
        return _length;
    }
    
    /**
     * Obtiene el primer elemento de la cola.
     * @return Primer elemento en la cola de prioridad
     */
    public SLLNode getFirst() {
        return _first;
    }
    ////////////////////////////////////////////////////////////////////////////
    
    /**
     * Dice si la cola esta vacia o no.
     * @return true si la cola esta completamente vacia, false de lo contrario
     */
    public boolean isEmpty () {
        return (_length == 0);
    }
    
    /**
     * Obtiene y elimina el primer elemento de la cola.
     * @return Primer elemento de la cola
     */
    public Node dequeue () {
        if (_first == null) {
            throw new NoSuchElementException();
        }
        else {
            Node tmp = (Node) _first.getElement();
            removeFirst();
            return tmp;
        }
    }
    
    /**
     * Elimina todos los elemento de la cola y la deja completamente vacia.
     */
    public void clear () {
        _first = null;
        _length = 0;
    }
    
    /**
     * Añade un elemento al funal de la cola
     * @param pElem Elemento para añadir al nodo nuevo de la cola
     */
    public void add (Node pElem) {
        SLLNode pred = null, curr = _first;
        
        if (curr == null) {
        }
        else {
            Node nNode = (Node) curr.getElement();
            while ((curr != null) && (pElem.getDistance() >= (nNode.getDistance()))) {
                pred = curr;
                curr = curr.getSucc();
            }
        }
        
        SLLNode ins = new SLLNode(pElem, curr);
        if (pred == null) {
            _first = ins;
        }
        else {
            pred.setSucc(ins);
        }
        _length++;
    }
    
    /**
     * Remueve un nodo de la cola con su respectivo elemento, sin retornarlo al usuario.
     */
    public void removeFirst () {
        //Remueve el primer elemento de la cola.
        if (_first == null) {
            throw new NoSuchElementException();
        }
        else {
            _first = _first.getSucc();
            _length--;
        }
    }
}